package org.spring.aop.framework;

import lombok.Getter;
import org.tool.core.lang.Assert;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;

/**
 * Spring 对 AOP Alliance {@link org.aopalliance.intercept.MethodInvocation}接口的实现，实现了扩展的{@link ProxyMethodInvocation}接口。
 * <p>
 * <b>NOTE:</b> 此类被认为是内部的，不应直接访问。它公开的唯一原因是与现有框架集成（例如 Pitchfork）的兼容性。
 * 对于任何其他目的，请改用 {@link ProxyMethodInvocation} 接口。
 *
 * @author 李坤
 * @date 2022/4/18 13:45
 */
@Getter
public class ReflectiveMethodInvocation implements ProxyMethodInvocation {

    /**
     * 原始的代理对象
     */
    protected final Object proxy;
    /**
     * 要调用的目标方法
     */
    protected final Method method;
    /**
     * 要调用的目标对象
     */
    protected final Object target;
    /**
     * 要调用的目标方法的参数
     */
    protected Object[] arguments;


    /**
     * 使用给定的参数构造一个新的 ReflectiveMethodInvocation。
     *
     * @param target    要调用的目标对象
     * @param method    调用的方法
     * @param arguments 调用方法的参数
     */
    public ReflectiveMethodInvocation(Object target, Method method, Object[] arguments, Object proxy) {
        Assert.notNull(target, "Target object must not be null");

        this.proxy = proxy;
        this.target = target;
        this.method = method;
        this.arguments = arguments;
    }

    @Override
    public Object getThis() {
        return target;
    }

    @Override
    public AccessibleObject getStaticPart() {
        return method;
    }

    @Override
    public Object proceed() throws Throwable {
        return method.invoke(target, arguments);
    }

}
